package com.project.school_flate.serviceimpl.shop;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.project.school_flate.dto.delivery.DeliveryInfoDto;
import com.project.school_flate.dto.shop.ShopAccountDto;
import com.project.school_flate.entity.delivery.DeliveryInfo;
import com.project.school_flate.entity.delivery.table.DeliveryInfoTableDef;
import com.project.school_flate.entity.order.table.OrderTakeawayTableDef;
import com.project.school_flate.entity.shop.ShopAccount;
import com.project.school_flate.entity.shop.ShopInfo;
import com.project.school_flate.entity.shop.table.ShopAccountTableDef;
import com.project.school_flate.entity.shop.table.ShopInfoTableDef;
import com.project.school_flate.entity.table.shop.ShopAccountTable;
import com.project.school_flate.mapper.order.OrderTakeawayMapper;
import com.project.school_flate.mapper.shop.ShopAccountMapper;
import com.project.school_flate.mapper.shop.ShopInfoMapper;
import com.project.school_flate.service.shop.ShopAccountService;
import com.project.school_flate.util.HttpClientUtil;
import com.project.school_flate.util.Md5Util;
import com.project.school_flate.util.PoToDTO;
import com.project.school_flate.util.Result.Result;
import com.project.school_flate.util.system.ComVariableUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.List;

/**
 *  服务层实现。
 *
 * @author 马维健
 * @since 2024/1/2
 */
@Service
public class ShopAccountServiceImpl extends ServiceImpl<ShopAccountMapper, ShopAccount> implements ShopAccountService {

    @Autowired
    private ShopAccountMapper oShopAccountMapper;

    @Autowired
    private OrderTakeawayMapper oOrderTakeawayMapper;

    @Autowired
    private ShopInfoMapper oShopInfoMapper;

    // 微信公众号授权登录请求的网址
    public static final String WX_LOGIN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";

    /**
     * 获取店铺账号
     * @param oShopAccountDto
     * @return
     * @throws Exception
     */
    @Override
    public Result getShopAccount(ShopAccountDto oShopAccountDto) throws Exception {
        List<ShopAccount> oShopAccountList = new ArrayList<>();
        long total = 0;
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(ShopAccountTable.SHOP_ACCOUNT.STATE.eq(1));
        //判断是否传入ID
        if(StringUtils.isNotBlank(oShopAccountDto.getId())){
            queryWrapper.where(ShopAccountTable.SHOP_ACCOUNT.ID.eq(oShopAccountDto.getId()));
        }
        queryWrapper.orderBy("create_time desc");
        //是否分页
        if(oShopAccountDto.getPage() != null && oShopAccountDto.getLimit() != null){
            Page<ShopAccount> ShopAccountPage = oShopAccountMapper.paginateWithRelations(oShopAccountDto.getPage(),oShopAccountDto.getLimit(),queryWrapper);
            oShopAccountList = ShopAccountPage.getRecords();
            total = ShopAccountPage.getTotalRow();
        }else{
            oShopAccountList = oShopAccountMapper.selectListWithRelationsByQuery(queryWrapper);
            total = oShopAccountList.size();
        }
        //PoToDto
        List<ShopAccountDto> oShopAccountDtoList = (List<ShopAccountDto>) PoToDTO.poToDtoList(oShopAccountList,new ShopAccountDto());
        return Result.ok(oShopAccountDtoList,total);
    }

    /**
     * 添加店铺账号
     * @param oShopAccountDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result addShopAccount(ShopAccountDto oShopAccountDto) throws Exception {
        ShopAccount oShopAccount = new ShopAccount();
        PoToDTO.poToDto(oShopAccountDto,oShopAccount);
        if(oShopAccountMapper.insert(oShopAccount) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("添加店铺账号失败");
        }
        return Result.ok("添加店铺账号成功");
    }

    /**
     * 修改店铺账号
     * @param oShopAccountDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result updateShopAccount(ShopAccountDto oShopAccountDto) throws Exception {
        ShopAccount oShopAccount = new ShopAccount();
        PoToDTO.poToDto(oShopAccountDto,oShopAccount);
        if(oShopAccountMapper.update(oShopAccount) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("修改店铺账号失败");
        }
        return Result.ok("修改店铺账号成功");
    }

    /**
     * 删除店铺账号
     * @param oShopAccountDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result deleteShopAccount(ShopAccountDto oShopAccountDto) throws Exception {
        ShopAccount oShopAccount = new ShopAccount();
        PoToDTO.poToDto(oShopAccountDto,oShopAccount);
        if(oShopAccountMapper.deleteById(oShopAccount.getId()) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("删除店铺账号失败");
        }
        return Result.ok("删除店铺账号成功");
    }

    /**
     * 冻结店铺账号
     * @param oShopAccountDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result freezeShopAccount(ShopAccountDto oShopAccountDto) throws Exception {
        ShopAccount oShopAccount = new ShopAccount();
        PoToDTO.poToDto(oShopAccountDto,oShopAccount);
        //获取店铺账号下的店铺
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(ShopInfoTableDef.SHOP_INFO.ACCOUNT_ID.eq(oShopAccount.getId()));
        List<ShopInfo> oShopInfoList = oShopInfoMapper.selectListByQuery(queryWrapper);
        if(CollectionUtils.isNotEmpty(oShopInfoList)){
            List<String> oShopInfoIdList = new ArrayList<>();
            oShopInfoList.forEach(item->{oShopInfoIdList.add(item.getId());});
            //判断店铺是否还有订单未完成
            queryWrapper.where(OrderTakeawayTableDef.ORDER_TAKEAWAY.SHOP_ID.in(oShopInfoIdList));
            queryWrapper.where(OrderTakeawayTableDef.ORDER_TAKEAWAY.PAY_STATE.notIn(2,4,6));
            if(CollectionUtils.isNotEmpty(oOrderTakeawayMapper.selectListByQuery(queryWrapper))){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Result.error("店铺还有未完成的订单");
            }
        }
        oShopAccount.setState(0);
        if(oShopAccountMapper.update(oShopAccount) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("冻结店铺账号失败");
        }
        return Result.ok("冻结店铺账号成功");
    }

    /**
     * 获取店铺账号（后台）
     * @param oShopAccountDto
     * @return
     * @throws Exception
     */
    @Override
    public Result getShopAccountBack(ShopAccountDto oShopAccountDto) throws Exception {
        List<ShopAccount> oShopAccountList = new ArrayList<>();
        long total = 0;
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.orderBy("create_time desc");
        //是否分页
        if(oShopAccountDto.getPage() != null && oShopAccountDto.getLimit() != null){
            Page<ShopAccount> ShopAccountPage = oShopAccountMapper.paginateWithRelations(oShopAccountDto.getPage(),oShopAccountDto.getLimit(),queryWrapper);
            oShopAccountList = ShopAccountPage.getRecords();
            total = ShopAccountPage.getTotalRow();
        }else{
            oShopAccountList = oShopAccountMapper.selectListWithRelationsByQuery(queryWrapper);
            total = oShopAccountList.size();
        }
        //PoToDto
        List<ShopAccountDto> oShopAccountDtoList = (List<ShopAccountDto>) PoToDTO.poToDtoList(oShopAccountList,new ShopAccountDto());
        return Result.ok(oShopAccountDtoList,total);
    }

    /**
     * 解冻店铺账号
     * @param oShopAccountDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result thawShopAccount(ShopAccountDto oShopAccountDto) throws Exception {
        ShopAccount oShopAccount = new ShopAccount();
        PoToDTO.poToDto(oShopAccountDto,oShopAccount);
        oShopAccount.setState(1);
        if(oShopAccountMapper.update(oShopAccount) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("解冻店铺账号失败");
        }
        return Result.ok("解冻店铺账号成功");
    }

    /**
     * 注册店铺账号
     * @param oShopAccountDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result registerShopAccount(ShopAccountDto oShopAccountDto) throws Exception {
        ShopAccount oShopAccount = new ShopAccount();
        PoToDTO.poToDto(oShopAccountDto,oShopAccount);
        //判断手机号是否存在
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(ShopAccountTable.SHOP_ACCOUNT.PHONE.eq(oShopAccount.getPhone()));
        if(CollectionUtils.isNotEmpty(oShopAccountMapper.selectListByQuery(queryWrapper))){
            return Result.error("手机号已存在");
        }
        //判断openId是否存在
        queryWrapper = new QueryWrapper();
        queryWrapper.where(ShopAccountTable.SHOP_ACCOUNT.WX_OPTION_ID.eq(oShopAccount.getWxOptionId()));
        ShopAccount openShopAccount = oShopAccountMapper.selectOneByQuery(queryWrapper);
        if(StringUtils.isNotBlank(openShopAccount.getPhone())){
            return Result.error("微信号已存在，请前往登录");
        }
        openShopAccount.setPhone(oShopAccount.getPhone());
        openShopAccount.setPassword(Md5Util.code(oShopAccount.getPassword()));
        if(oShopAccountMapper.update(openShopAccount) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("注册店铺失败");
        }
        return Result.ok("注册店铺成功");
    }

    /**
     * 登录店铺账号
     * @param oShopAccountDto
     * @return
     * @throws Exception
     */
    @Override
    public Result loginShopAccount(ShopAccountDto oShopAccountDto) throws Exception {
        ShopAccount oShopAccount = new ShopAccount();
        PoToDTO.poToDto(oShopAccountDto,oShopAccount);
        //判断手机号是否存在
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(ShopAccountTable.SHOP_ACCOUNT.PHONE.eq(oShopAccount.getPhone()));
        ShopAccount oldShopAccount = oShopAccountMapper.selectOneWithRelationsByQuery(queryWrapper);
        if(oldShopAccount == null){
            return Result.error("手机号不存在");
        }
        //判断密码是否正确
        if(!oldShopAccount.getPassword().equals(Md5Util.code(oShopAccount.getPassword()))){
            return Result.error("密码错误");
        }
        //判断openId是否一样
        if(!oldShopAccount.getWxOptionId().equals(oShopAccount.getWxOptionId())){
            return Result.error("此微信绑定的不是当前手机号");
        }
        //PoToDto
        ShopAccountDto shopAccountDto = new ShopAccountDto();
        PoToDTO.poToDto(oldShopAccount,shopAccountDto);
        shopAccountDto.setPassword("******");
        //用户登录
        StpUtil.login(shopAccountDto.getId());
        //登录缓存登录对象
        StpUtil.getSession().set("shopAccount", shopAccountDto);
        shopAccountDto.setToken(StpUtil.getTokenValue());
        return Result.ok(shopAccountDto);
    }

    /**
     * 退出店铺账号
     * @param oShopAccountDto
     * @return
     * @throws Exception
     */
    @Override
    public Result exitShopAccount(ShopAccountDto oShopAccountDto) throws Exception {
        //获取当前店铺
        ShopAccount oShopAccount = new ShopAccount();
        PoToDTO.poToDto(oShopAccountDto,oShopAccount);
        if(StpUtil.isLogin()){
            oShopAccount = (ShopAccount) StpUtil.getSession().get("shopAccount");
            if(oShopAccount == null || StringUtils.isBlank(oShopAccount.getId())){
                return Result.fail("当前登陆人失效");
            }
        }else{
            return Result.fail("当前登陆人失效");
        }
        StpUtil.logout(oShopAccount.getId());
        return Result.ok();
    }

    /**
     * 店铺账号修改密码
     * @param oShopAccountDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result updateShopAccountPassword(ShopAccountDto oShopAccountDto) throws Exception {
        ShopAccount oShopAccount = new ShopAccount();
        PoToDTO.poToDto(oShopAccountDto,oShopAccount);
        //获取密码
        ShopAccount oldShopAccount = oShopAccountMapper.selectOneById(oShopAccount.getId());
        if(!oldShopAccount.getPassword().equals(Md5Util.code(oShopAccountDto.getOldPassword()))){
            return Result.error("原密码错误");
        }
        oShopAccount.setPassword(Md5Util.code(oShopAccount.getPassword()));
        if(oShopAccountMapper.update(oShopAccount) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("修改密码失败");
        }
        //退出登录
        StpUtil.logout(oShopAccount.getId());
        return Result.ok("修改密码成功，请重新登录");
    }

    @Value("${loginTest}")
    private String loginTest;

    /**
     * 公众号登录店铺账号
     * @param oShopAccountDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result loginShopAccountOfficial(ShopAccountDto oShopAccountDto) throws Exception {
        ShopAccountDto shopAccountDto = new ShopAccountDto();
        if(Boolean.valueOf(loginTest)){
            ShopAccount oShopAccount = oShopAccountMapper.selectOneById("139537928921681920");
            PoToDTO.poToDto(oShopAccount,shopAccountDto);
        }else{
            //需要拿客户端获得的code换取openId
            String url = String.format(WX_LOGIN_URL, ComVariableUtil.getSystemValue("wx_appid"), ComVariableUtil.getSystemValue("wx_secret"), oShopAccountDto.getCode());
            //调用微信api授权
            String data = HttpClientUtil.doGet(url);
            //解析返回的json字符串
            JSONObject jsonObject = JSONObject.parseObject(data);
            //获取openid和token值
            String openId = jsonObject.getString("openid");
            String accessToken = jsonObject.getString("access_token");
            if (StringUtils.isEmpty(openId)) {
                return Result.fail("未获取到openId");
            }
            //通过openId获取配送员信息
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.where(ShopAccountTableDef.SHOP_ACCOUNT.WX_OPTION_ID.eq(openId));
            ShopAccount oldShopAccount = oShopAccountMapper.selectOneByQuery(queryWrapper);
            if(oldShopAccount == null){
                // 通过openid 和 accessToken 来获取用户信息
                // 拼接请求地址
                String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
                requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
                //发送请求
                String urlRequest = HttpClientUtil.doGet(requestUrl);
                //解析返回的json字符串
                JSONObject userInfo = JSONObject.parseObject(urlRequest);
                //获取用户微信昵称和头像
                String nickname = userInfo.getString("nickname");
                String avatar = userInfo.getString("headimgurl");
                //新增配送员
                ShopAccount oShopAccount = new ShopAccount();
                oShopAccount.setName(nickname);
                oShopAccount.setWxOptionId(openId);
                oShopAccount.setImage(avatar);
                if(oShopAccountMapper.insert(oShopAccount) == 0){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return Result.error("店铺账号公众号登录失败");
                }
                PoToDTO.poToDto(oShopAccount,shopAccountDto);
            }else{
                PoToDTO.poToDto(oldShopAccount,shopAccountDto);
            }
        }
        return Result.ok(shopAccountDto);
    }

}
